<template>
    <div class="add-wrap">
        <!-- 顶部：步骤条 -->
        <div class="step-header">
            <div class="side left">
                <a-button @click="prevStep">上一步</a-button>
            </div>

            <div class="center">
                <a-steps :current="current" labelPlacement="vertical" class="steps">
                    <a-step title="基础信息" />
                    <a-step title="频道选择" />
                    <a-step title="频道配置" />
                </a-steps>
            </div>

            <div class="side right" v-if="current < maxStep">
                <a-button type="primary" :disabled="nextDisabled" @click="nextStep">下一步</a-button>
            </div>
            <div class="side right" v-else>
                <a-button type="primary" :loading="saving" @click="onSave">
                    {{ isEdit ? '保存修改' : '保存' }}
                </a-button>
            </div>
        </div>

        <!-- 内容 -->
        <div class="content-card">
            <!-- 基础信息 -->
            <BaseInfo v-show="current === 0" ref="baseInfoRef" :initial="editInitial?.baseInfo || null" />

            <!-- 频道选择 -->
            <ChannelSelect v-show="current === 1" ref="channelSelectRef" :active="current === 1"
                :providedList="channelListProvided" :initialSelectedIds="editInitial?.selectedChannelIds || []"
                :initialSelectedNames="editInitial?.selectedChannelNames || []" :appId="editAppId || undefined"
                @valid-change="onChannelValidChange" @ids-change="onIdsChange" />

            <!-- 频道配置 -->
            <ChannelConfig v-show="current === 2" ref="channelConfigRef" :active="current === 2"
                :selectedIds="selectedChannelIds" :initialRows="editInitial?.channelConfigs || []"
                :appId="editAppId || undefined" />
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import { useRoute, useRouter } from 'vue-router'
import BaseInfo from './components/BaseInfo.vue'
import ChannelSelect from './components/ChannelSelect.vue'
import ChannelConfig from './components/ChannelConfig.vue'
import api from '@/api/api'
import type { SearchAppAddPayload, SearchAppUpdatePayload } from '@/api/api'

const route = useRoute()
const router = useRouter()

/** 步骤控制 */
const current = ref(0)
const maxStep = 2
const saving = ref(false)

/** —— 编辑态 —— */
type EditInitial = {
    baseInfo: { appName: string; node: string; logoUrl?: string }
    selectedChannelIds: Array<number | string>
    selectedChannelNames: string[]
    channelConfigs: Array<{
        rowKey: number | string
        id: number | string
        name: string
        displayName: string
        visible: boolean
        channelId?: string | number
        appId?: string | number
    }>
}

const editInitial = ref<EditInitial | null>(null)
const editAppId = ref<number | string | null>(null)
const isEdit = computed(() => !!route.query.id)

const channelListProvided = ref<any[] | null>(null)

/**  编辑初始化结构 */
function mapDetailToInitial(detail: any): EditInitial {
    const sa = detail?.search_app ?? detail?.searchApp ?? detail ?? {}

    const appName = sa?.app_name ?? sa?.name ?? ''
    const nodeName = sa?.node_name ?? sa?.node ?? ''
    const logoUrl = sa?.app_icon ?? sa?.logo ?? undefined

    const rawChannels: any[] = detail?.channel_list ?? detail?.channels ?? []

    const selectedIds = rawChannels
        .map((ch) => ch.id ?? ch.channel_id ?? ch.app_channel_id)
        .filter((v) => v !== undefined && v !== null)

    const selectedNames = rawChannels
        .map((ch) => (ch.channel_name ?? ch.name ?? '').toString())
        .filter((v) => !!v)

    const channelConfigs = rawChannels.map((ch: any, idx: number) => {
        const id = ch.id ?? ch.channel_id ?? ch.app_channel_id ?? idx
        const name = ch.channel_name ?? ch.name ?? ''
        return {
            rowKey: id,
            id,
            name,
            displayName: ch.channel_show_name ?? ch.displayName ?? name,
            visible: String(ch.channel_show ?? 'true') !== 'false',
            channelId: ch.channel_id ?? id,
            appId: ch.app_id
        }
    })

    return {
        baseInfo: { appName, node: nodeName, logoUrl },
        selectedChannelIds: selectedIds,
        selectedChannelNames: selectedNames,
        channelConfigs
    }
}

/** 按 app_id 过滤拉取频道列表 */
async function loadChannelListOnce() {
    try {
        const params: any = {}
        if (editAppId.value != null) params.app_id = editAppId.value
        const res: any = await api.searchAppChannelList(params)
        channelListProvided.value = (res && res.data) || []
    } catch {
        channelListProvided.value = []
    }
}

async function loadEditInitial(appId: string) {
    const res: any = await api.searchAppGetById({ id: appId })
    const detail = res?.data ?? res
    editAppId.value = detail?.id ?? detail?.app_id ?? appId
    editInitial.value = mapDetailToInitial(detail)
    await loadChannelListOnce()
}

/** 初始化 */
onMounted(async () => {
    if (isEdit.value) {
        const id = String(route.query.id || '')
        await loadEditInitial(id)
    }
})

/** 子组件 */
const baseInfoRef = ref<{
    validate: () => Promise<void>
    getBaseInfo: () => {
        appName: string
        node: string
        logoUrl?: string
        logoFile?: File | null
    }
} | null>(null)

const channelSelectRef = ref<{
    validate: () => Promise<void>
    isValid: boolean
    getSelectedRows: () => any[]
    getSelectedIds: () => (number | string)[]
} | null>(null)

const channelConfigRef = ref<{
    getAllRows: () => Array<{
        rowKey: number | string
        id: number | string
        name: string
        displayName: string
        visible: boolean
        channelId?: string | number
        appId?: string | number
    }>
} | null>(null)

/** 下一步 */
const channelValid = ref(false)
function onChannelValidChange(v: boolean) {
    channelValid.value = v
}

const selectedChannelIds = ref<(number | string)[]>([])
function onIdsChange(ids: (number | string)[]) {
    selectedChannelIds.value = [...ids]
}

const nextDisabled = computed(() => current.value === 1 && !channelValid.value)

/** 上一步/下一步 */
function prevStep() {
    if (current.value <= 0) {
        router.push({ path: '/' })
        return
    }
    current.value -= 1
}
async function nextStep() {
    if (current.value === 0) {
        try {
            await baseInfoRef.value?.validate()
            current.value = 1
        } catch { }
        return
    }
    if (current.value === 1) {
        try {
            await channelSelectRef.value?.validate()
            const ids = channelSelectRef.value?.getSelectedIds() || []
            selectedChannelIds.value = [...ids]
            current.value = 2
        } catch { }
        return
    }
}

/** ===== 生成提交 ===== */
function buildChannelListForSubmit() {
    const configs = channelConfigRef.value?.getAllRows() || []
    const idsFromSelect = selectedChannelIds.value || []
    const idSet = new Set(idsFromSelect)

    const baseList: Array<any> =
        configs.length
            ? configs.filter((row) => idSet.has(row.id))
            : idsFromSelect.map((id) => ({
                rowKey: id,
                id,
                name: String(id),
                displayName: String(id),
                visible: true,
                channelId: id,
                appId: undefined
            }))

    // 编辑态
    const appIdForChannel = isEdit.value ? String(editAppId.value ?? '') : ''

    return baseList.map((row: any, idx: number) => ({
        channel_name: String(row.name ?? ''),
        channel_show: row.visible ? 'true' : 'false',
        channel_show_name: String(row.displayName ?? row.name ?? ''),
        channel_sort: idx + 1,
        app_id: row.appId != null ? String(row.appId) : appIdForChannel,
        channel_id: String(row.channelId ?? row.id)
    }))
}

/** 保存 */
async function onSave() {
    try {
        saving.value = true
        await baseInfoRef.value?.validate()
        await channelSelectRef.value?.validate()

        const base = baseInfoRef.value?.getBaseInfo()
        if (!base) throw new Error('基础信息缺失')

        const idsFromSelect = channelSelectRef.value?.getSelectedIds() || []
        if (!idsFromSelect.length) throw new Error('请至少选择一个频道')

        const channelList = buildChannelListForSubmit()
        if (!channelList.length) {
            Modal.warning({
                title: '提示',
                content: '未找到频道配置，将按选择的频道默认生成基础配置。'
            })
        }

        // 图标
        const appIcon = base.logoUrl && !base.logoUrl.startsWith('blob:') ? base.logoUrl : ''

        if (!isEdit.value) {
            const payload: SearchAppAddPayload = {
                app_name: base.appName,
                node_name: base.node,
                app_icon: appIcon,
                app_status: 'active',
                unit_name: '技术部',
                channel_list: channelList
            }
            await api.searchAppAdd(payload)
            message.success('新增成功')
        } else {
            const updatePayload: SearchAppUpdatePayload = {
                id: editAppId.value ?? route.query.id,
                app_id: editAppId.value ?? route.query.id,
                app_name: base.appName,
                node_name: base.node,
                app_icon: appIcon,
                app_status: 'active',
                unit_name: '技术部',
                channel_list: channelList
            }
            await api.searchAppUpdate(updatePayload)
            message.success('修改成功')
        }

        router.push({ path: '/' })
    } catch (err: any) {
        message.error(err?.message || (isEdit.value ? '修改失败，请检查表单' : '保存失败，请检查表单'))
    } finally {
        saving.value = false
    }
}
</script>

<style scoped lang="less">
@bg-page: #f0f2f5;
@border-card: #e9edf3;

.add-wrap {
    min-height: 100vh;
    background: @bg-page;
    display: flex;
    flex-direction: column;
    padding: 12px;
    box-sizing: border-box;
}

.step-header {
    position: relative;
    height: 100px;
    background: #fff;
    border: 1px solid @border-card;
    border-radius: 4px;
    box-sizing: border-box;
    margin-bottom: 15px;
}

.side {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

.left {
    left: 16px;
}

.right {
    right: 16px;
}

.center {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    --side-safe: 140px;
    width: calc(100% - var(--side-safe) * 2);
    max-width: 980px;
    min-width: 320px;
}

.steps :deep(.ant-steps) {
    width: 100%;
}

.content-card {
    flex: 1;
    background: #fff;
    border: 1px solid @border-card;
    border-radius: 4px;
    padding: 16px 16px 24px;
    overflow: auto;
    box-sizing: border-box;
}
</style>
